package com.jinmdz.fmis.api.api.service;

import com.jinmdz.fmis.api.api.model.common.BusinessCharges;
import com.jinmdz.fmis.api.api.model.common.IdData;
import com.jinmdz.fmis.api.api.model.common.IdVersionData;
import com.jinmdz.fmis.api.api.model.transport.TransportAllData;
import com.jinmdz.fmis.api.api.model.transport.TransportAllFuneralData;
import com.jinmdz.fmis.api.api.model.transport.TransportAllLoadData;
import com.jinmdz.fmis.api.api.model.transport.TransportTaskData;
import com.jinmdz.fmis.api.base.BaseService;
import com.jinmdz.fmis.api.constant.MessageConst;
import com.jinmdz.fmis.api.model.config.dictionary.BusinessLogCode;
import com.jinmdz.fmis.api.model.config.dictionary.OperationLogCode;
import com.jinmdz.fmis.api.model.config.dictionary.TransportStatusCode;
import com.jinmdz.fmis.api.model.system.UserItem;
import com.jinmdz.fmis.api.wrapper.ChargeWrapper;
import com.jinmdz.fmis.api.wrapper.DictionaryWrapper;
import com.jinmdz.fmis.api.wrapper.OperationWrapper;
import com.jinmdz.fmis.common.ext.StringBuilderExt;
import com.jinmdz.fmis.common.util.BeanUtil;
import com.jinmdz.fmis.common.util.DataUtil;
import com.jinmdz.fmis.common.util.DateUtil;
import com.jinmdz.fmis.core.base.BaseResult;
import com.jinmdz.fmis.core.constant.EBusinessType;
import com.jinmdz.fmis.core.constant.EDictCode;
import com.jinmdz.fmis.core.exception.ActionException;
import com.jinmdz.fmis.core.util.JacksonUtil;
import com.jinmdz.fmis.dao.dao.*;
import com.jinmdz.fmis.dao.model.charge.ChargeItem;
import com.jinmdz.fmis.dao.model.funeral.FamilyMemberItem;
import com.jinmdz.fmis.dao.model.funeral.FuneralBusinessViewItem;
import com.jinmdz.fmis.dao.model.service.ServiceItem;
import com.jinmdz.fmis.dao.model.transport.TransportCodeText;
import com.jinmdz.fmis.dao.model.transport.TransportTaskItem;
import com.jinmdz.fmis.dao.model.transport.TransportTaskViewItem;
import com.jinmdz.fmis.mapper.entity.ChargeItemEntity;
import com.jinmdz.fmis.mapper.entity.FuneralBusinessLogEntity;
import com.jinmdz.fmis.mapper.entity.TransportTaskEntity;
import com.jinmdz.fmis.mapper.entity.TransportTaskPorterEntity;
import com.jinmdz.fmis.mapper.mapper.TransportTaskMapper;
import com.jinmdz.fmis.mapper.mapper.TransportTaskPorterMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

/**
 * TransportTaskService类
 *
 * @author LiCongLu
 * @date 2020-01-20 10:23
 */
@Service("transportTaskService")
public class TransportTaskService extends BaseService {

    @Resource
    private FuneralBusinessDao funeralBusinessDao;

    @Resource
    private TransportTaskMapper transportTaskMapper;

    @Resource
    private TransportTaskPorterMapper transportTaskPorterMapper;

    @Resource
    private TransportStatusCode transportStatusCode;

    @Resource
    private ServiceItemDao serviceItemDao;

    @Resource
    private ChargeItemDao chargeItemDao;

    @Resource
    private TransportTaskDao transportTaskDao;

    @Resource
    private TransportTaskPorterDao transportTaskPorterDao;

    @Resource
    private ChargeWrapper chargeWrapper;

    @Resource
    private DictionaryService dictionaryService;

    @Resource
    private UserService userService;

    @Resource
    private OperationLogCode operationLogCode;

    @Resource
    private BusinessLogCode businessLogCode;

    @Resource
    private OperationWrapper operationWrapper;

    @Resource
    private DictionaryWrapper dictionaryWrapper;

    @Resource
    private FamilyMemberDao familyMemberDao;


    /**
     * 根据transport_task表中id加载接运任务信息
     *
     * @param data 接运任务主键
     * @return
     * @author LiCongLu
     * @date 2020-02-13 9:44
     */
    public BaseResult<TransportTaskData> loadTransportTaskWithId(IdData data) {
        Integer loadId = data.getId();
        // 查询业务信息
        TransportTaskViewItem loadItem = transportTaskDao.getTransportTaskViewById(loadId);
        if (DataUtil.isNull(loadItem) || DataUtil.isNull(loadItem.getId(), loadItem.getVersion())) {
            return failure("主键错误，不存在此业务信息");
        }
        TransportTaskData loadData = loadTransportTaskData(loadItem);

        // 返回响应结果
        return successData(loadData);
    }

    /**
     * 获取业务费用等数据
     *
     * @param loadItem 已加载数据
     * @return
     * @author LiCongLu
     * @date 2020-02-16 10:30
     */
    private TransportTaskData loadTransportTaskData(TransportTaskViewItem loadItem) {
        // 创建响应实体，并赋值
        TransportTaskData loadData = BeanUtil.copy2Bean(loadItem, new TransportTaskData());
        // 获取业务费用及物品服务
        loadData.setCharges(new BusinessCharges());

        ChargeItem businessCharge = chargeItemDao.getChargeItemById(loadItem.getChargeId());
        loadData.getCharges().setBusinessCharge(businessCharge);

        // 业务费用主键
        Integer businessChargeId = businessCharge != null ? businessCharge.getId() : 0;

        ArrayList<ChargeItem> goodsServices = chargeItemDao.listChargeItemByRandomCode(loadItem.getBusinessCode(), loadItem.getRandomCode(), businessChargeId);
        loadData.getCharges().setGoodsServices(goodsServices);
        //设置文本值
        dictionaryWrapper.resetDataText(loadData);
        //查询抬尸工的集合
        ArrayList<TransportCodeText> transportTaskPorterList = transportTaskPorterDao.listSystemUserIdAndTextByTransportTaskId(loadItem.getId());
        //查询要加载的抬尸工集合
        ArrayList<Integer> transportTaskPorter = new ArrayList<Integer>();
        if (!transportTaskPorterList.isEmpty()) {
            for (int i = 0; i < transportTaskPorterList.size(); i++) {
                transportTaskPorter.add(transportTaskPorterList.get(i).getId());
            }
        }
        //设置回显示id
        loadData.setTransportTaskPorter(transportTaskPorter);
        //设置回显idtext
        loadData.setTransportTaskPorterList(transportTaskPorterList);
        return loadData;
    }

    /**
     * 保存接运任务信息到transport_task表中
     *
     * @param userItem 当前帐号
     * @param data     火化信息数据
     * @return
     * @author LiCongLu
     * @date 2020-02-13 9:40
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult saveTransportTask(UserItem userItem, TransportTaskData data) throws ActionException {
        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            throw exception(MessageConst.NO_FUNERAL_CODE);
        }

        Integer id = data.getId();
        // 主键不为空
        if (DataUtil.valid(id)) {
            updateTransportTask(userItem, funeralItem, data);
        } else {
            id = insertTransportTask(userItem, funeralItem, data);
        }
        return loadTransportTaskWithId(new IdData(id));
    }

    /**
     * 插入接运任务信息
     *
     * @param userItem    当前帐号
     * @param funeralItem 殡葬业务
     * @param data        新增接运信息
     * @return
     * @author LiCongLu
     * @date 2020-02-13 9:48
     */
    private Integer insertTransportTask(UserItem userItem, FuneralBusinessViewItem funeralItem, TransportTaskData data) throws ActionException {
        // 创建接运实体
        TransportTaskEntity entity = getEntity(userItem, TransportTaskEntity.class);

        // 判断流程状态
        if (!DataUtil.inIntegers(data.getProcessStateCode()
                , transportStatusCode.getYiYuYue()
                , transportStatusCode.getWeiChuChe()
                , transportStatusCode.getYiChuChe()
                , transportStatusCode.getYiFanHui()
                , transportStatusCode.getFanKongChe())) {
            throw exception("接运状态值错误");
        }

        // 覆盖数据
        BeanUtil.copy2Bean(data, entity);

        // 创建业务随机码
        entity.setRandomCode(DataUtil.getUUID());

        // 依照状态等设置默认值
        saveTransportTaskValue(entity);

        // 插入业务费用
        ChargeItem businessCharge = data.getCharges().getBusinessCharge();
        businessCharge.setBusinessCode(entity.getBusinessCode())
                .setRandomCode(entity.getRandomCode())
                .setItemNumber(data.getRuleNumber())
                .setItemUnit(data.getRuleUnit());

        // 验证是否不可结算
        checkBusinessChargeUnsettled(entity, businessCharge);

        // 车辆用途
        String transportPurpose = dictionaryWrapper.getDataText(EDictCode.TRANSPORT_CAR_USE, data.getTransportPurposeCode());
        String dictCode = EDictCode.TRANSPORT_CAR_TYPE.getCode();
        int chargeId = chargeWrapper.insertBusinessCharge(userItem, businessCharge, dictCode, entity.getTransportCarTypeCode(), transportPurpose, data.getRuleRemark());
        entity.setChargeId(chargeId);

        // 插入物品服务
        ArrayList<ChargeItemEntity> chargeEntities = chargeWrapper.insertGoodsServices(userItem, entity.getBusinessCode(), entity.getRandomCode(), EBusinessType.USE_IN_TRANSPORT_TASK.getType(), data.getCharges().getGoodsServices());

        // 新增接运任务
        transportTaskMapper.insertTransportTask(entity);
        // 判断保存接运信息结果
        if (DataUtil.invalid(entity.getId())) {
            throw exception("保存接运信息失败");
        }

        // 处理抬尸工
        if (DataUtil.valid(data.getTransportTaskPorter())) {
            // 去重
            data.setTransportTaskPorter(DataUtil.repeatArrayList(data.getTransportTaskPorter()));
            for (Integer userId : data.getTransportTaskPorter()) {
                if (DataUtil.invalid(userId)) {
                    continue;
                }
                TransportTaskPorterEntity porterEntity = getEntity(userItem, TransportTaskPorterEntity.class);
                porterEntity.setTransportTaskId(entity.getId())
                        .setSystemUserId(userId);
                transportTaskPorterMapper.insertTransportTaskPorter(porterEntity);
                if (DataUtil.invalid(porterEntity.getId())) {
                    throw exception("保存接运任务抬尸工信息失败");
                }
            }
        }

        // 添加业务及操作日志
        Integer logTypeCode = operationLogCode.getTransportTaskInsert();
        Integer chargeLogTypeCode = operationLogCode.getChargeInsert();
        saveTransportTaskLog(userItem, funeralItem, data, entity, logTypeCode, chargeLogTypeCode, businessCharge, chargeEntities, null);

        return entity.getId();
    }

    /**
     * 验证是否不可结算
     *
     * @param entity         数据实体
     * @param businessCharge 业务费用
     * @return
     * @author LiCongLu
     * @date 2020-05-15 10:37
     */
    private void checkBusinessChargeUnsettled(TransportTaskEntity entity, ChargeItem businessCharge) throws ActionException {
        boolean unsettled = false;
        // 判断条件：1.返空车；2.非返空车时，行驶里程等于零
        if (DataUtil.inIntegers(entity.getProcessStateCode()
                , transportStatusCode.getFanKongChe())) {
            unsettled = true;
        } else if (entity.getTransportDistance() == null) {
            unsettled = true;
        } else if (new BigDecimal(0).compareTo(entity.getTransportDistance()) == 0) {
            unsettled = true;
        }

        // 设置不可结算状态
        businessCharge.setAsUnsettled(unsettled ? 1 : 0);
    }

    /**
     * 添加接运任务日志记录
     *
     * @param userItem          当前帐号
     * @param funeralItem       当前业务
     * @param data              请求数据
     * @param entity            数据实体
     * @param logTypeCode       日志记录类型
     * @param chargeLogTypeCode 费用日志类型
     * @param businessCharge    业务费用
     * @param chargeEntities    费用记录
     * @param deleteEntities    删除费用记录
     * @return
     * @author LiCongLu
     * @date 2020-02-25 11:22
     */
    private void saveTransportTaskLog(UserItem userItem, FuneralBusinessViewItem funeralItem
            , TransportTaskData data, TransportTaskEntity entity
            , Integer logTypeCode, Integer chargeLogTypeCode
            , ChargeItem businessCharge, ArrayList<ChargeItemEntity> chargeEntities, ArrayList<ChargeItemEntity> deleteEntities) throws ActionException {

        // 添加业务日志及操作日志
        String businessCode = funeralItem.getBusinessCode();
        Integer typeCode = getLogTypeForStateCode(entity.getProcessStateCode());
        FuneralBusinessLogEntity businessLogEntity = operationWrapper.businessLog(userItem, businessCode, typeCode);

        // 操作日志字符串
        StringBuilderExt builder = new StringBuilderExt();
        builder.format("保存接运信息，业务编码[{0}]，逝者姓名[{1}]，预约车型[{2}][{3}]，预约时间[{4}]，接运状态[{5}]，接尸地点[{6}]，车牌号[{7}]，司机姓名[{8}]" +
                        " ，接运费用[{9}]，操作人员[{10}]"
                , businessCode, funeralItem.getDeadName()
                , String.valueOf(entity.getTransportCarTypeCode())
                , dictionaryWrapper.getDataText(EDictCode.TRANSPORT_CAR_TYPE, entity.getTransportCarTypeCode())
                , dictionaryWrapper.getDataText(EDictCode.TRANSPORT_CAR_TASK_STATUS, entity.getProcessStateCode())
                , DateUtil.formatPattern16(entity.getDepartureTime())
                , entity.getTransportCarNo(), entity.getDriverUserName()
                , DataUtil.getPlainString(businessCharge.getItemCharge()), userItem.getFullName());

        // 添加日志
        operationWrapper.operationLog(userItem, businessLogEntity, logTypeCode, builder.toString()
                , JacksonUtil.obj2Json(data), null, JacksonUtil.obj2Json(entity));

        // 累计费用总金额
        if (DataUtil.valid(chargeEntities)) {
            BigDecimal sumCharge = new BigDecimal(0);
            for (ChargeItemEntity chargeEntity : chargeEntities) {
                sumCharge = sumCharge.add(chargeEntity.getItemCharge());
            }
            // 添加物品服务费用日志
            builder.clear();
            builder.format("保存接运信息更新物品服务，业务编码[{0}]，逝者姓名[{1}]，接运费用[{2}]，物品服务总金额[{3}]"
                    , businessCode, funeralItem.getDeadName()
                    , DataUtil.getPlainString(businessCharge.getItemCharge()), DataUtil.getPlainString(sumCharge));
            operationWrapper.operationLog(userItem, businessLogEntity, chargeLogTypeCode
                    , builder.toString(), JacksonUtil.obj2Json(data.getCharges().getGoodsServices()), null, JacksonUtil.obj2Json(chargeEntities));
        }

        // 删除费用总金额
        if (DataUtil.valid(deleteEntities)) {
            BigDecimal sumCharge = new BigDecimal(0);
            for (ChargeItemEntity chargeEntity : deleteEntities) {
                sumCharge = sumCharge.add(chargeEntity.getItemCharge());
            }
            // 删除物品服务费用日志
            builder.clear();
            builder.format("保存接运信息删除物品服务，业务编码[{0}]，逝者姓名[{1}]，删除物品服务总金额[{2}]"
                    , businessCode, funeralItem.getDeadName(), DataUtil.getPlainString(sumCharge));
            operationWrapper.operationLog(userItem, businessLogEntity, operationLogCode.getChargeDelete()
                    , builder.toString(), null, JacksonUtil.obj2Json(deleteEntities), null);
        }
    }

    /**
     * 验证流程状态值
     *
     * @param stateCode 流程状态值
     * @return
     * @author LiCongLu
     * @date 2020-02-24 17:20
     */
    private Integer getLogTypeForStateCode(Integer stateCode) throws ActionException {
        // 处理状态
        if (DataUtil.equals(stateCode, transportStatusCode.getYiYuYue())) {
            return businessLogCode.getTransportTaskYiYuYue();
        } else if (DataUtil.equals(stateCode, transportStatusCode.getWeiChuChe())) {
            return businessLogCode.getTransportTaskWeiChuChe();
        } else if (DataUtil.equals(stateCode, transportStatusCode.getYiChuChe())) {
            return businessLogCode.getTransportTaskYiYuYue();
        } else if (DataUtil.equals(stateCode, transportStatusCode.getYiFanHui())) {
            return businessLogCode.getTransportTaskYiYuYue();
        } else if (DataUtil.equals(stateCode, transportStatusCode.getFanKongChe())) {
            return businessLogCode.getTransportTaskYiYuYue();
        } else {
            throw exception("流转状态值错误");
        }
    }

    /**
     * 依据状态等设置默认值
     *
     * @param entity 数据实体
     * @return
     * @author LiCongLu
     * @date 2020-02-17 9:30
     */
    private void saveTransportTaskValue(TransportTaskEntity entity) throws ActionException {
        Date nowDate = nowDate();

        // 判断车辆编号
        if (DataUtil.isNull(entity.getTransportCarNo())) {
            entity.setTransportCarNo("");
        }

        // 先设置默认非反空车
        entity.setAsEmptyCar(0);

        Integer stateCode = entity.getProcessStateCode();
        if (DataUtil.equals(stateCode, transportStatusCode.getYiYuYue())) {
        } else if (DataUtil.equals(stateCode, transportStatusCode.getWeiChuChe())) {
        } else if (DataUtil.equals(stateCode, transportStatusCode.getYiChuChe())) {
            if (DataUtil.isNull(entity.getDepartureTime())) {
                // 已出车状态，但未填写出车时间的，补充当前时间
                entity.setDepartureTime(nowDate);
            }
        } else if (DataUtil.equals(stateCode, transportStatusCode.getYiFanHui())) {
            if (DataUtil.isNull(entity.getReturnTime())) {
                // 已返回状态，但未填写回车时间的，补充当前时间
                entity.setReturnTime(nowDate);
            }
        } else if (DataUtil.equals(stateCode, transportStatusCode.getFanKongChe())) {
            // 设置反空车
            entity.setAsEmptyCar(1);
        } else {
            throw exception("流转状态值错误");
        }

        // 判断时间节点
        if (DataUtil.noNullOrEmpty(entity.getDepartureTime(), entity.getReturnTime())) {
            if (entity.getDepartureTime().after(entity.getReturnTime())) {
                throw exception("出车时间晚于回车时间");
            }
        }
    }

    /**
     * 更新接运任务信息
     *
     * @param userItem    当前帐号
     * @param funeralItem 殡葬业务
     * @param data        更新接运任务信息
     * @return
     * @author LiCongLu
     * @date 2020-02-13 9:48
     */
    private void updateTransportTask(UserItem userItem, FuneralBusinessViewItem funeralItem, TransportTaskData data) throws ActionException {
        // 验证主键和数据版本是否存在
        if (DataUtil.isNull(data.getId(), data.getVersion())) {
            throw exception("请求接运信息主键与版本号不能为空");
        }

        // 判断接运费用
        ChargeItem businessCharge = data.getCharges().getBusinessCharge();
        if (DataUtil.invalid(businessCharge.getId())) {
            throw exception("请求接运费用主键不能为空");
        }

        // 通过主键获取接运信息
        TransportTaskEntity entity = transportTaskMapper.getTransportTaskById(data.getId());
        if (DataUtil.isNull(entity) || DataUtil.isNull(entity.getId(), entity.getVersion())) {
            throw exception("接运主键错误，不存在此接运任务");
        }

        // 验证业务编码
        if (!data.getBusinessCode().equals(entity.getBusinessCode())) {
            throw exception(MessageConst.BUSINESS_CODE_ERROR);
        }

        // 验证接运信息版本
        if (!DataUtil.equals(data.getVersion(), entity.getVersion())) {
            throw exception(versionError("接运信息"));
        }

        // 判断流程状态值
        if (!DataUtil.inIntegers(data.getProcessStateCode()
                , transportStatusCode.getYiYuYue()
                , transportStatusCode.getWeiChuChe()
                , transportStatusCode.getYiChuChe()
                , transportStatusCode.getYiFanHui()
                , transportStatusCode.getFanKongChe())) {
            throw exception("接运状态值错误");
        }

        // 判断流程状态
        if (data.getProcessStateCode().intValue() < entity.getProcessStateCode().intValue()) {
            throw exception("接运状态值不允许回退选择");
        }

        // 验证业务与业务费用是否匹配
        if (businessCharge.getId().intValue() != entity.getChargeId().intValue()
                || !businessCharge.getBusinessCode().equals(entity.getBusinessCode())) {
            throw exception("业务费用与业务不匹配");
        }

        // 覆盖家属数据
        BeanUtil.copy2Bean(data, entity);

        // 依照状态等设置默认值
        saveTransportTaskValue(entity);

        // 更新业务费用
        businessCharge.setBusinessCode(entity.getBusinessCode())
                .setRandomCode(entity.getRandomCode())
                .setItemNumber(data.getRuleNumber())
                .setItemUnit(data.getRuleUnit())
                .setId(entity.getChargeId());

        // 验证是否不可结算
        checkBusinessChargeUnsettled(entity, businessCharge);

        // 车辆用途
        String transportPurpose = dictionaryWrapper.getDataText(EDictCode.TRANSPORT_CAR_USE, data.getTransportPurposeCode());
        String dictCode = EDictCode.TRANSPORT_CAR_TYPE.getCode();
        chargeWrapper.updateBusinessCharge(userItem, businessCharge, dictCode, data.getTransportCarTypeCode(), transportPurpose, data.getRuleRemark());

        // 业务费用主键
        Integer businessChargeId = businessCharge != null ? businessCharge.getId() : 0;

        // 更新物品服务
        ArrayList<ChargeItemEntity> chargeEntities = chargeWrapper.updateGoodsServices(userItem, entity.getBusinessCode(), entity.getRandomCode(), EBusinessType.USE_IN_TRANSPORT_TASK.getType(), businessChargeId, data.getCharges().getGoodsServices());

        // 删除物品服务
        ArrayList<ChargeItemEntity> deleteEntities = chargeWrapper.deleteGoodsServices(userItem, entity.getBusinessCode(), entity.getRandomCode(), EBusinessType.USE_IN_TRANSPORT_TASK.getType(), data.getCharges().getDeleteIds());

        // 设置修改帐号
        entity.setModifiedUserId(userItem.getId());
        // 更新接运信息
        transportTaskMapper.updateTransportTask(entity);

        // 更新抬尸工
        updateTransportTaskPorter(userItem, data, entity);

        // 添加业务及操作日志
        Integer logTypeCode = operationLogCode.getTransportTaskUpdate();
        Integer chargeLogTypeCode = operationLogCode.getChargeUpdate();
        saveTransportTaskLog(userItem, funeralItem, data, entity, logTypeCode, chargeLogTypeCode, businessCharge, chargeEntities, deleteEntities);
    }

    /**
     * 更新接运任务抬尸工信息
     *
     * @param userItem 当前帐号
     * @param data     接运数据
     * @param entity   接运任务
     * @return
     * @author LiCongLu
     * @date 2020-02-13 15:30
     */
    private void updateTransportTaskPorter(UserItem userItem, TransportTaskData data, TransportTaskEntity entity) throws
            ActionException {

        // 处理抬尸工
        if (DataUtil.invalid(data.getTransportTaskPorter())) {
            // 清除抬尸工
            transportTaskPorterDao.deletedForTransportTaskPorter(entity.getId(), userItem.getId());
        } else {
            // 去重
            data.setTransportTaskPorter(DataUtil.repeatArrayList(data.getTransportTaskPorter()));

            // 处理抬尸工
            ArrayList<Integer> userIds = transportTaskPorterDao.listSystemUserIdByTransportTaskId(data.getId());
            for (Integer userId : data.getTransportTaskPorter()) {
                if (DataUtil.invalid(userId)) {
                    continue;
                }
                if (userIds.contains(userId)) {
                    userIds.remove(userId);
                } else {
                    TransportTaskPorterEntity porterEntity = getEntity(userItem, TransportTaskPorterEntity.class);
                    porterEntity.setTransportTaskId(entity.getId())
                            .setSystemUserId(userId);
                    transportTaskPorterMapper.insertTransportTaskPorter(porterEntity);
                    if (DataUtil.isNull(porterEntity.getId())) {
                        throw exception("保存接运任务抬尸工信息失败");
                    }
                }
            }

            // 去除多余的抬尸工
            if (userIds.size() > 0) {
                // 清除抬尸工
                transportTaskPorterDao.deletedForTransportTaskPorterByUserIds(entity.getId(), userItem.getId(), userIds);
            }
        }
    }

    /**
     * 删除火化任务
     *
     * @param
     * @return
     * @author LiCongLu
     * @date 2020-02-14 14:28
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult deleteTransportTaskWithId(UserItem userItem, IdVersionData data) throws ActionException {
        // 通过主键获取接运信息
        TransportTaskViewItem loadItem = transportTaskDao.getTransportTaskViewById(data.getId());
        if (DataUtil.isNull(loadItem) || DataUtil.isNull(loadItem.getId(), loadItem.getVersion())) {
            return failure("主键错误，不存在此接运业务");
        }

        // 验证接运信息版本
        if (!DataUtil.equals(loadItem.getVersion(), data.getVersion())) {
            return failure(versionError("接运信息"));
        }

        //判断状态，已出车、已返回、返空车等状态不能删除
        if (DataUtil.inIntegers(loadItem.getProcessStateCode()
                , transportStatusCode.getYiChuChe()
                , transportStatusCode.getYiFanHui()
                , transportStatusCode.getFanKongChe())) {
            return failure("已出车、已返回、返空车等状态不能删除");
        }

        // 记录费用主键
        ArrayList<Integer> chargeIds = new ArrayList<>();
        // 判断业务费用是否存在
        ChargeItem businessCharge = chargeItemDao.getChargeItemById(loadItem.getChargeId());
        if (businessCharge != null) {
            // 判断是否结算
            if (DataUtil.valid(businessCharge.getAsSettled())) {
                return failure("接运业务费用已经结算，无法进行删除");
            }
            chargeIds.add(businessCharge.getId());
        }

        // 业务费用主键
        Integer businessChargeId = businessCharge != null ? businessCharge.getId() : 0;

        // 判断是否已经存在结算
        ArrayList<ChargeItem> goodsServices = chargeItemDao.listChargeItemByRandomCode(loadItem.getBusinessCode(), loadItem.getRandomCode(), businessChargeId);
        if (goodsServices != null && goodsServices.size() > 0) {
            for (ChargeItem chargeItem : goodsServices) {
                if (DataUtil.valid(chargeItem.getAsSettled())) {
                    return failure("接运物品服务已经结算，无法进行删除");
                }
                chargeIds.add(chargeItem.getId());
            }
        }

        // 删除抬尸工
        ArrayList<Integer> transportTaskPorter = transportTaskPorterDao.listSystemUserIdByTransportTaskId(data.getId());
        if (transportTaskPorter.size() > 0) {
            transportTaskPorterDao.deletedForTransportTaskPorterByUserIds(loadItem.getId(), userItem.getId(), transportTaskPorter);
        }

        // 删除费用
        if (chargeIds.size() > 0) {
            chargeItemDao.deletedForChargeItem(loadItem.getBusinessCode(), chargeIds, userItem.getId());
        }

        // 删除业务任务
        transportTaskMapper.deletedForTransportTask(loadItem.getId(), userItem.getId(), loadItem.getVersion());

        // 删除日志信息
        deleteTransportTaskLog(userItem, loadItem, businessCharge, goodsServices);

        return success("删除完成");
    }

    /**
     * 删除接运日志
     *
     * @param userItem       当前账号
     * @param loadItem       接运任务
     * @param businessCharge 业务费用
     * @param goodsServices  物品服务
     * @return
     * @author LiCongLu
     * @date 2020-02-25 15:57
     */
    private void deleteTransportTaskLog(UserItem userItem, TransportTaskItem loadItem, ChargeItem businessCharge, ArrayList<ChargeItem> goodsServices) throws ActionException {
        // 添加业务日志及操作日志
        String businessCode = loadItem.getBusinessCode();
        Integer typeCode = businessLogCode.getTransportTaskDelete();
        FuneralBusinessLogEntity businessLogEntity = operationWrapper.businessLog(userItem, businessCode, typeCode);
        // 操作日志字符串
        StringBuilderExt builder = new StringBuilderExt();
        builder.format("删除接运信息，业务编码[{0}]，操作人员[{1}]", businessCode, userItem.getFullName());
        // 添加日志
        Integer logTypeCode = operationLogCode.getTransportTaskDelete();
        operationWrapper.operationLog(userItem, businessLogEntity, logTypeCode, builder.toString(), null, JacksonUtil.obj2Json(loadItem), null);

        // 累计费用总金额
        if (DataUtil.valid(goodsServices)) {
            Integer chargeLogTypeCode = operationLogCode.getChargeDelete();
            BigDecimal sumCharge = new BigDecimal(0);
            for (ChargeItem chargeItem : goodsServices) {
                sumCharge = sumCharge.add(chargeItem.getItemCharge());
            }
            // 记录业务费用
            goodsServices.add(businessCharge);
            // 添加物品服务费用日志
            builder.clear();
            builder.format("删除接运信息物品服务，业务编码[{0}]，接运费用[{1}]，物品服务总金额[{2}]", businessCode
                    , DataUtil.getPlainString(businessCharge.getItemCharge()), DataUtil.getPlainString(sumCharge));
            operationWrapper.operationLog(userItem, businessLogEntity, chargeLogTypeCode
                    , builder.toString(), null, JacksonUtil.obj2Json(goodsServices), null);
        }
    }

    /**
     * 接运任务，界面权限验证及基础数据加载
     *
     * @param data 加载全部数据
     * @return
     * @author LiCongLu
     * @date 2020-02-16 10:22
     */
    public BaseResult<TransportAllLoadData> loadTransportTaskAll(TransportAllData data) {
        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            return failure(MessageConst.NO_FUNERAL_CODE);
        }

        TransportAllLoadData allLoadData = new TransportAllLoadData();

        // 加载业务数据
        if (DataUtil.valid(data.getTransportTaskId())) {
            // 查询业务信息
            TransportTaskViewItem loadItem = transportTaskDao.getTransportTaskViewById(data.getTransportTaskId());
            if (DataUtil.noNullOrEmpty(loadItem)) {
                // 验证业务编码
                if (!businessCode.equals(loadItem.getBusinessCode())) {
                    return failure(MessageConst.BUSINESS_CODE_ERROR);
                }
                TransportTaskData loadData = loadTransportTaskData(loadItem);
                allLoadData.setTransportTask(loadData);
            }
        }

        // 当不存在接运任务时，需要获取家属信息
        if (DataUtil.isNull(allLoadData.getTransportTask())) {
            FamilyMemberItem familyMemberItem = familyMemberDao.getFamilyMemberByBusinessCode(businessCode);
            TransportAllFuneralData funeralData = new TransportAllFuneralData();
            funeralData.setTransportLinkman(familyMemberItem.getMemberName())
                    .setTransportTelephone(familyMemberItem.getMobilePhone());
            allLoadData.setFuneralData(funeralData);
        }
        // 设置字典文本
        dictionaryWrapper.resetDataText(allLoadData.getFuneralData());

        // 加载字典数据
        allLoadData.setDicts(dictionaryService.loadDictionaryMap(data.getDictTypeCodes()));

        // 加载服务规则
        String dictCode = EDictCode.TRANSPORT_CAR_TYPE.getCode();
        allLoadData.setRuleItems(serviceItemDao.listServiceDictionaryRuleByDictCode(dictCode, ""));

        // 加载用户数据
        if (DataUtil.valid(data.getUserRoleCodes())) {
            allLoadData.setUsers(userService.loadRoleUserMap(data.getUserRoleCodes()));
        }

        // 记载物品服务
        if (DataUtil.valid(data.getServiceItemTypeCode())) {
            String businessType = EBusinessType.USE_IN_TRANSPORT_TASK.getType();
            ArrayList<ServiceItem> serviceItems = serviceItemDao.listServiceItemByBusinessType(businessType);
            HashMap<String, ArrayList<ServiceItem>> dataMap = new HashMap<>(16);
            dataMap.put(businessType, serviceItems);
            allLoadData.setServiceItems(dataMap);
        }

        // 返回响应结果
        return successData(allLoadData);
    }
}
